package cn.bonoon.controllers;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.batatasframework.web.RequestParameterReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import cn.bonoon.controllers.announcement.AnnouncementUtils;
import cn.bonoon.core.plugins.AnnouncementService;
import cn.bonoon.entities.interacting.AnnouncementEntity;
import cn.bonoon.kernel.AccessAuthorityResolver;
import cn.bonoon.kernel.io.FileManager;
import cn.bonoon.kernel.menus.ChannelDefinition;
import cn.bonoon.kernel.menus.MenuDefinition;
import cn.bonoon.kernel.menus.ModuleDefinition;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.menus.PartDefinition;
import cn.bonoon.kernel.menus.StyleGetter;
import cn.bonoon.kernel.menus.privileges.PrivilegeInspector;
import cn.bonoon.kernel.security.LogonUser;
import cn.bonoon.kernel.support.services.UserService;
import cn.bonoon.kernel.util.MD5Util;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.kernel.web.controllers.AbstractController;
import cn.bonoon.kernel.web.models.JsonResult;
import cn.bonoon.kernel.web.models.LayoutModel;
import cn.bonoon.util.UrlKeyHelper;

/**
 * <pre>
 * 系统的首页和各个子系统的首页的定义
 * 
 * 系统首页的访问路径的规则，以"/"开头为系统首页的路径
 * 
 * </pre>
 * @author jackson
 *
 */
@Controller
@RequestMapping("s")
public class HostController extends AbstractController{
	
	private final static int MAX_SIZE = 7;
	
	@Autowired
	private ModuleManager moduleManager;
	@Autowired
	private UserService userService;
	@Autowired
	private FileManager fileManager;
	
	private String errPicSrc;
	
	@Override
	public void afterPropertiesSet() throws Exception {
		
		this.errPicSrc = moduleManager.getResourceServer().resource("/res/images/subsystem.png");
		super.afterPropertiesSet();
	}
	
	/** 子系统的首页页面 */
	@RequestMapping(value = "{key}!sys.do")
	public ModelAndView module(HttpServletRequest request, @PathVariable("key") String key){
		try{
			LogonUser user = getUser();
			if(!user.allowAccess()){
				/*
				 * 这里是不允许访问子系统，那么应该跳转到平台的主页面上来吧
				 * 这个不允许访问是不允许访问整个系统？如果是这样，那才应该跳转到相应的提示界面
				 */
				return new ModelAndView(new RedirectView(moduleManager.getDefaultEndpoint()));
			}
			
			ModuleDefinition module = moduleManager.module(key);
			Assert.notNull(module, "要访问的子系统不存在！");
			
			PrivilegeInspector privilege = userService.policy().privilege(user, module);
			LayoutModel layout = buildLayout(key, request, "首页", module, user);
			
			RequestParameterReader reader = RequestParameterReader.valueOf(request);
			layout.buildChannel(module, user, reader, privilege, null);
			
			//添加用户定义的快捷菜单
			//不一定有菜单
			StringBuilder subsystemmain = new StringBuilder();
			
			ModelAndView mav = internalParse(key, layout, module, user, subsystemmain);
			
			return mav;
		}catch(Throwable ex){
			return errorPanel(ex);
		}
	}
	
	/** 人个进入时，整个系统的工作平台的首页 */
	@RequestMapping
	public ModelAndView get(HttpServletRequest request){
		try{
			LogonUser user = getUser();
			AccessAuthorityResolver resolver = AccessAuthorityResolver.valueOf(applicationContext, user);
			if(!user.allowAccess()){
				return resolver.gotoHome();
			}
			ModuleDefinition mi = moduleManager.module();
			
			LayoutModel layout = buildLayout(mi.getId(), request, "首页", moduleManager, user);
			PrivilegeInspector privilege = userService.policy().privilege(user, mi);
			
			RequestParameterReader reader = RequestParameterReader.valueOf(request);
			layout.buildChannel(mi, user, reader, privilege, null);
			
			StringBuilder hostmain = new StringBuilder();
			hostmain.append("<div data-settings=\"iconClassname:'icon-sys'\" title='子系统'>");
			hostmain.append("<table style='width:100%' cellpadding='15' cellspacing='0'><tr>");
			int i = 1;
			for(ModuleDefinition module : resolver.resolveModules()){
				i = _parse(i, hostmain, module, errPicSrc);
			}
			for(; i <= MAX_SIZE; i++){ hostmain.append("<td></td>"); }
			
			hostmain.append("<td></td></tr></table><hr style='width:90%;'/>");
			
			return internalParse(null, layout, mi, user, hostmain.append("</div>"));
		}catch(Throwable ex){
			return errorPanel(ex);
		}
	}

	/** 生成用于控制界面框架的layout */
	private LayoutModel buildLayout(String mid, HttpServletRequest request, String title, StyleGetter styleGetter, LogonUser user){
		LayoutModel layout = new LayoutModel(mid, request, moduleManager);
		layout.initLayout(title, styleGetter.getStyle(), styleGetter.getDescribe());
		return layout;
	}
	
	/** 这里构造首页工作区的内容 */
	private ModelAndView internalParse(String key, LayoutModel layout, ModuleDefinition mi, LogonUser user, StringBuilder hostmain) throws Exception{
		
		for(PartDefinition part : mi.getParts()){
			if(part.checked(user)){
				hostmain.append("<div title='").append(part.getName()).append("'");
				if(StringHelper.isNotEmpty(part.getIconCls())){
					hostmain.append("data-settings=\"iconClassname:'").append(part.getIconCls()).append("'\"");
				}
				hostmain.append(" href='").append(part.getUrl()).append("'></div>");
			}
		}
		
		layout.addObject("hostmain", hostmain).addObject("key", UrlKeyHelper.filter(key));
		
		layout.addObject("content", parseAnnouncement(announcementService.moduleAnnouncements(user, key, 0)));

		layout.addObject("authentication", user);
		
		if(null != key){
			//获取最近的一条公告信息
			layout.addObject("firContent", parseAnnouncement(announcementService.newests(user, key, 1)));
		}
		
		return layout.execute("sys/sys-index");
	}
	private final String id = MD5Util.randomMD5String();

	@Autowired
	private AnnouncementService announcementService;
	
	private StringBuilder parseAnnouncement(List<AnnouncementEntity> announcement) throws Exception {
		return AnnouncementUtils.parseAnnouncement(announcement, fileManager);
	}

	@RequestMapping("announcement.dlg")
	public String announcementDialog(Model model, @RequestParam(value = "key", required = false) String key) {
		try{
			model.addAttribute("id", id);
			model.addAttribute("attrs", "title='公告' style='width:700px;height:500px;'");
			model.addAttribute("content", parseAnnouncement(announcementService.moduleAnnouncements(getUser(), key, 0)));
			model.addAttribute("key", UrlKeyHelper.filter(key));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "simple-dialog.vm");
		return "/sys/sys-announcement";
	}
	
	@ResponseBody
	@RequestMapping(value = "announcement.load", method = { RequestMethod.GET, RequestMethod.POST })
	public JsonResult announcementLoading(
			@RequestParam(value = "page", defaultValue = "0") int page, 
			@RequestParam(value = "key", required = false) String key) {
		try{
			return JsonResult.result(parseAnnouncement(announcementService.moduleAnnouncements(getUser(), key, page)).toString());
		}catch(Exception ex){
			return JsonResult.result(ex);
		}
	}
	
	//菜单的点击事件t
	private static final String click = "var menuTitle = this.title;" +
			"if(jQuery('#tabs-sys-settings-management').buptab('exists', menuTitle)){" +
			"jQuery('#tabs-sys-settings-management').buptab('select', menuTitle);}else{" +
			"var content = '<iframe scrolling=\"auto\" frameborder=\"0\" src=\"'+this.href+'\" style=\"width:100%;height:100%;\"></iframe>';" +
			"jQuery('#tabs-sys-settings-management').buptab('add', {content:content,title:menuTitle,closable:true});}return false;";
	
	/** 进入个人中心的界面，这个是在子系统里进入 */
	@RequestMapping("user/{key}!settings.do")
	public ModelAndView settings(HttpServletRequest request, @PathVariable("key") String key){
		return __settings(request, key);
	}
	
	/** 个人中心，在系统平台进入 */
	@RequestMapping("user/settings.do")
	public ModelAndView settings(HttpServletRequest request){
		return __settings(request, "info");
	}
	
	private ModelAndView __settings(HttpServletRequest request, String key){
		try{
			LogonUser user = getUser();
			
			PrivilegeInspector privilege = userService.policy().privilege(user, moduleManager.module().getId(), moduleManager.getChannelManager().getId());
			ChannelDefinition personalCenter = moduleManager.personalCenter();			
			LayoutModel layout = buildLayout(key, request, personalCenter.navigation(), moduleManager, user);
			
			RequestParameterReader reader = RequestParameterReader.valueOf(request);
			layout.buildChannel(personalCenter.getModule(), user, reader, privilege, personalCenter.getId());

			StringBuilder menus = layout.menuBuilder();
			MenuDefinition selected = null;
			
			String id = personalCenter.idSubmenu(key);
			
			for(MenuDefinition item : personalCenter){
				//TODO 这里需要进行操作权限的限制
				menus.append("<li><span>");
				if(item.selected(id)){
					key = item.getId();
					item.button(menus, "menuSelected");
					selected = item;
				}else{
					item.button(menus, "");
				}
				menus.append("</span></li>");
			}
			layout.setMenuOnClick(click);
			
			if(null != selected){
				StringBuilder block = layout.getBlock();
				block.append("jQuery('#tabs-sys-settings-management').buptab('add', {content:'<iframe scrolling=\"auto\" frameborder=\"0\" src=\"");
				block.append(selected.getHref()).append("\" style=\"width:100%;height:100%;\"></iframe>',title:'").append(selected.getName()).append("'});");
			}
			
			return layout.execute("sys/sys-settings-management");
		}catch(Throwable ex){
			return errorPanel(ex);
		}
	}
	
	private int _parse(int i, StringBuilder html, ModuleDefinition mi, String errSrc) {
		html.append("<td style='width:100px;' valign='top' align='center'><a href='")
				.append(mi.getEndpoint()).append("'><img width='64px' src='")
				.append(mi.getThumbnail())
				.append("' onerror=\"this.onerror=null;this.src='")
				.append(errSrc).append("'\"/></a><p><a href='")
				.append(mi.getEndpoint()).append("'>").append(mi.getName())
				.append("</a></p>");
		if (i < MAX_SIZE) {
			return i + 1;
		} else {
			html.append("<td></td><tr></tr>");
		}
		return 1;
	}
}
